package com.beerandjesus.sportofkings.handicapper.model;

/**
 * Class representing a mixed number or mixed fraction.
 *
 * Strictly, a mixed numeral is the sum of a non-zero integer and a proper fraction;
 * however, this class makes no efforts to reduce a number, so improper fractions in
 * the standard representation (i.e., toString()) are displayed as given.
 *
 * Additionally, when the numerator and denomenator are 0, the number value is an integer.
 * A MixedNumeral created with 0, 0 and 0 is the number 0.
 *
 * Any negative integer in the integer, numerator, or denomenator position causes the
 * result to be a negative number.
 *
 * Date: May 28, 2012
 * Time: 9:34:06 AM
 */
public class MixedNumeral {
    private int integer;
    private int numerator;
    private int denomenator;
    private static final String SOLIDUS = "/";
    private static final String SPACE = " ";


    /**
     * Get a new MixedNumeral.
     *
     * @param integer The integer
     * @param numerator The numerator; if zero, denomenator must be zero
     * @param denomenator The denomenator; if zero, numerator must be zero
     */
    public MixedNumeral(int integer, int numerator, int denomenator) {
        if (numerator+denomenator != 0 && (numerator == 0 || denomenator == 0)) {
            throw new IllegalArgumentException("Non-zero numerator or denomenator with zero numerator or denomenator is not allowed");
        }
        if ((numerator < 0 || denomenator < 0)) {
            if (integer > 0) {
                integer = 0 - integer;
            }
            if (integer == 0 && numerator > 0) {
                numerator = 0 - numerator;
            }
            if (integer < 0) {
                numerator = Math.abs(numerator);
            }
            denomenator = Math.abs(denomenator);
        }
        this.integer = integer;
        this.numerator = numerator;
        this.denomenator = denomenator;
    }

    public int getInteger() {
        return integer;
    }

    public int getNumerator() {
        return numerator;
    }

    public int getDenomenator() {
        return denomenator;
    }

    /**
     * The standard representation of the number.
     * @return
     */
    @Override
    public String toString() {
        if (numerator == 0 || denomenator == 0) {
            return "" + integer;
        }
        StringBuffer sb = new StringBuffer();
        if (integer != 0) {
            sb.append(integer + SPACE);
        }
        sb.append(numerator + SOLIDUS + denomenator);
        return sb.toString();
    }

    /**
     * A representation of the number as an improper fraction (e.g., whole
     * numbers show as <i>integer</i>/1). The denomenator is not changed.
     *
     * @return
     */
    public String toImproperFractionString() {
        if (integer == 0 && denomenator == 0) {
            return "0";
        }
        if ((integer < 0 || numerator < 0) && integer != 0) {
            int n = (integer * denomenator) - numerator;
            return n  + SOLIDUS + denomenator;
        }
        if (integer != 0 && denomenator != 0) {
            int n = (integer * denomenator) + numerator;
            return n  + SOLIDUS + denomenator;

        } else if (denomenator == 0) {
            return integer + SOLIDUS + "1";
        } else {
            return numerator + SOLIDUS + denomenator;
        }
    }
}
